home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / shells / tcshsrc.zoo / tcsh / tc.printf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-25  |  7.1 KB  |  316 lines

  1. /* $Header: /home/hyperion/mu/christos/src/sys/tcsh-6.00/RCS/tc.printf.c,v 3.1 1991/07/15 19:37:24 christos Exp $ */
  2. /*
  3.  * tc.printf.c: A public-domain, minimal printf/sprintf routine that prints
  4.  *           through the putchar() routine.  Feel free to use for
  5.  *           anything...  -- 7/17/87 Paul Placeway
  6.  */
  7. /*-
  8.  * Copyright (c) 1980, 1991 The Regents of the University of California.
  9.  * All rights reserved.
  10.  *
  11.  * Redistribution and use in source and binary forms, with or without
  12.  * modification, are permitted provided that the following conditions
  13.  * are met:
  14.  * 1. Redistributions of source code must retain the above copyright
  15.  *    notice, this list of conditions and the following disclaimer.
  16.  * 2. Redistributions in binary form must reproduce the above copyright
  17.  *    notice, this list of conditions and the following disclaimer in the
  18.  *    documentation and/or other materials provided with the distribution.
  19.  * 3. All advertising materials mentioning features or use of this software
  20.  *    must display the following acknowledgement:
  21.  *    This product includes software developed by the University of
  22.  *    California, Berkeley and its contributors.
  23.  * 4. Neither the name of the University nor the names of its contributors
  24.  *    may be used to endorse or promote products derived from this software
  25.  *    without specific prior written permission.
  26.  *
  27.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  28.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  29.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  30.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  31.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  32.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  33.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  34.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  35.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  36.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  37.  * SUCH DAMAGE.
  38.  */
  39. #include "config.h"
  40. RCSID("$Id: tc.printf.c,v 3.1 1991/07/15 19:37:24 christos Exp $")
  41.  
  42. #include "sh.h"
  43.  
  44. #ifdef lint
  45. #undef va_arg
  46. #define va_arg(a, b) (a ? (b) 0 : (b) 0)
  47. #endif
  48.  
  49. #define INF    32766        /* should be bigger than any field to print */
  50.  
  51. static unsigned char buf[128];
  52.  
  53. static    void    xaddchar    __P((int));
  54. static    void    doprnt        __P((void (*) __P((int)), char *, va_list));
  55.  
  56. static void
  57. doprnt(addchar, sfmt, ap)
  58.     void    (*addchar)();
  59.     char   *sfmt;
  60.     va_list ap;
  61. {
  62.     register unsigned char *f, *bp;
  63.     register long l;
  64.     register unsigned long u;
  65.     register int i;
  66.     register int fmt;
  67.     register unsigned char pad = ' ';
  68.     int     flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;
  69.     int     sign = 0;
  70.     int     attributes = 0;
  71.  
  72.  
  73.     f = (unsigned char *) sfmt;
  74.     for (; *f; f++) {
  75.     if (*f != '%') {    /* then just out the char */
  76.         (*addchar) ((int) (*f | attributes));
  77.     }
  78.     else {
  79.         f++;        /* skip the % */
  80.  
  81.         if (*f == '-') {    /* minus: flush left */
  82.         flush_left = 1;
  83.         f++;
  84.         }
  85.  
  86.         if (*f == '0' || *f == '.') {
  87.         /* padding with 0 rather than blank */
  88.         pad = '0';
  89.         f++;
  90.         }
  91.         if (*f == '*') {    /* field width */
  92.         f_width = va_arg(ap, int);
  93.         f++;
  94.         }
  95.         else if (Isdigit(*f)) {
  96.         f_width = atoi((char *) f);
  97.         while (Isdigit(*f))
  98.             f++;    /* skip the digits */
  99.         }
  100.  
  101.         if (*f == '.') {    /* precision */
  102.         f++;
  103.         if (*f == '*') {
  104.             prec = va_arg(ap, int);
  105.             f++;
  106.         }
  107.         else if (Isdigit(*f)) {
  108.             prec = atoi((char *) f);
  109.             while (Isdigit(*f))
  110.             f++;    /* skip the digits */
  111.         }
  112.         }
  113.  
  114.         if (*f == '#') {    /* alternate form */
  115.         hash = 1;
  116.         f++;
  117.         }
  118.  
  119.         if (*f == 'l') {    /* long format */
  120.         do_long = 1;
  121.         f++;
  122.         }
  123.  
  124.         fmt = *f;
  125.         if (Isupper(fmt)) {
  126.         do_long = 1;
  127.         fmt = Tolower(fmt);
  128.         }
  129.         bp = buf;
  130.         switch (fmt) {    /* do the format */
  131.         case 'd':
  132.         if (do_long)
  133.             l = va_arg(ap, long);
  134.         else
  135.             l = (long) (va_arg(ap, int));
  136.         if (l < 0) {
  137.             sign = 1;
  138.             l = -l;
  139.         }
  140.         do {
  141.             *bp++ = l % 10 + '0';
  142.         } while ((l /= 10) > 0);
  143.         if (sign)
  144.             *bp++ = '-';
  145.         f_width = f_width - (bp - buf);
  146.         if (!flush_left)
  147.             while (f_width-- > 0)
  148.             (*addchar) ((int) (pad | attributes));
  149.         for (bp--; bp >= buf; bp--)
  150.             (*addchar) ((int) (*bp | attributes));
  151.         if (flush_left)
  152.             while (f_width-- > 0)
  153.             (*addchar) ((int) (' ' | attributes));
  154.         break;
  155.  
  156.         case 'o':
  157.         case 'x':
  158.         case 'u':
  159.         if (do_long)
  160.             u = va_arg(ap, unsigned long);
  161.         else
  162.             u = (unsigned long) (va_arg(ap, unsigned));
  163.         if (fmt == 'u') {    /* unsigned decimal */
  164.             do {
  165.             *bp++ = u % 10 + '0';
  166.             } while ((u /= 10) > 0);
  167.         }
  168.         else if (fmt == 'o') {    /* octal */
  169.             do {
  170.             *bp++ = u % 8 + '0';
  171.             } while ((u /= 8) > 0);
  172.             if (hash)
  173.             *bp++ = '0';
  174.         }
  175.         else if (fmt == 'x') {    /* hex */
  176.             do {
  177.             i = u % 16;
  178.             if (i < 10)
  179.                 *bp++ = i + '0';
  180.             else
  181.                 *bp++ = i - 10 + 'a';
  182.             } while ((u /= 16) > 0);
  183.             if (hash) {
  184.             *bp++ = 'x';
  185.             *bp++ = '0';
  186.             }
  187.         }
  188.         i = f_width - (bp - buf);
  189.         if (!flush_left)
  190.             while (i-- > 0)
  191.             (*addchar) ((int) (pad | attributes));
  192.         for (bp--; bp >= buf; bp--)
  193.             (*addchar) ((int) (*bp | attributes));
  194.         if (flush_left)
  195.             while (i-- > 0)
  196.             (*addchar) ((int) (' ' | attributes));
  197.         break;
  198.  
  199.  
  200.         case 'c':
  201.         i = va_arg(ap, int);
  202.         (*addchar) ((int) (i | attributes));
  203.         break;
  204.  
  205.         case 's':
  206.         bp = va_arg(ap, unsigned char *);
  207.         if (!bp)
  208.             bp = (unsigned char *) "(nil)";
  209.         f_width = f_width - strlen((char *) bp);
  210.         if (!flush_left)
  211.             while (f_width-- > 0)
  212.             (*addchar) ((int) (pad | attributes));
  213.         for (i = 0; *bp && i < prec; i++) {
  214.             (*addchar) ((int) (*bp | attributes));
  215.             bp++;
  216.         }
  217.         if (flush_left)
  218.             while (f_width-- > 0)
  219.             (*addchar) ((int) (' ' | attributes));
  220.  
  221.         break;
  222.  
  223.         case 'a':
  224.         attributes = va_arg(ap, int);
  225.         break;
  226.  
  227.         case '%':
  228.         (*addchar) ((int) ('%' | attributes));
  229.         break;
  230.         }
  231.         flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;
  232.         sign = 0;
  233.         pad = ' ';
  234.     }
  235.     }
  236. }
  237.  
  238.  
  239. static unsigned char *xstring;
  240. static void
  241. xaddchar(c)
  242.     int     c;
  243. {
  244.     *xstring++ = c;
  245. }
  246.  
  247.  
  248. void
  249. /*VARARGS*/
  250. #if __STDC__
  251. xsprintf(char *str, char *fmt, ...)
  252. #else
  253. xsprintf(va_alist)
  254.     va_dcl
  255. #endif
  256. {
  257.     va_list va;
  258. #if __STDC__
  259.     va_start(va, fmt);
  260. #else
  261.     char *str, *fmt;
  262.  
  263.     va_start(va);
  264.     str = va_arg(va, char *);
  265.     fmt = va_arg(va, char *);
  266. #endif
  267.  
  268.     xstring = (unsigned char *) str;
  269.     doprnt(xaddchar, fmt, va);
  270.     va_end(va);
  271.     *xstring++ = '\0';
  272. }
  273.  
  274.  
  275. void
  276. /*VARARGS*/
  277. #if __STDC__
  278. xprintf(char *fmt, ...)
  279. #else
  280. xprintf(va_alist)
  281.     va_dcl
  282. #endif
  283. {
  284.     va_list va;
  285. #if __STDC__
  286.     va_start(va, fmt);
  287. #else
  288.     char   *fmt;
  289.  
  290.     va_start(va);
  291.     fmt = va_arg(va, char *);
  292. #endif
  293.     doprnt(xputchar, fmt, va);
  294.     va_end(va);
  295. }
  296.  
  297.  
  298. void
  299. xvprintf(fmt, va)
  300.     char   *fmt;
  301.     va_list va;
  302. {
  303.     doprnt(xputchar, fmt, va);
  304. }
  305.  
  306. void
  307. xvsprintf(str, fmt, va)
  308.     char   *str;
  309.     char   *fmt;
  310.     va_list va;
  311. {
  312.     xstring = (unsigned char *) str;
  313.     doprnt(xaddchar, fmt, va);
  314.     *xstring++ = '\0';
  315. }
  316.